<script setup lang="tsx">
import {onMounted, ref, watch} from "vue";
import {useMessage} from 'naive-ui'
import {useRoute} from "vue-router"
import {fetchDeleteRowByOrder, fetchGetMemberByOrder, fetchGetOrder, fetchUpdateOrder} from "@/service/api/order";
import {mapNumberToLetter} from "@/utils/common";
import DataInput from "@/views/common/executeorder/DataInput.vue";
import {useBoolean} from "~/packages/hooks";

const route = useRoute()
const orderData = ref<Api.Entity.Order>({
  id: 0,
  orderNo: ""
});
const showExcel = ref(true);
const message = useMessage();
const orderId = ref<number>(route.query.orderId ? Number(route.query.orderId) : 0);
const excel = ref();
const showBaseConfigModal = ref(false);
let width = window.innerWidth - 248;
let innerHeight = window.innerHeight;
let rowStartIndex = 4;
const rowStep = ref('5');
const currentMember = ref<Api.Entity.OrderMember>();
const config = ref<Excel.Config>({
  autoload: false,
  title: "订单",
  width: width,
  height: innerHeight - 160,
  lang: 'zh',
  showtoolbar: true,
  showinfobar: false,
  showtoolbarConfig: {
    chart: false,
    numberDecrease: false,
    numberIncrease: false,
  },
  cellRightClickConfig: {
    hideRow: false,
    hideColumn: false,
    chart: false,
  },
  hook: {
    // sheetMouseup: function (cell, position, sheet, moveState, ctx) {
    // rowStartIndex = position.r
    // console.log(position)
    // }
    // cellEditBefore: function (range) {
    // console.log("cellEditBefore:", range)
    // },
    deleteRCAfter: function (a, b, c, d) {
      // console.log("deleteRCAfter:", a, b, c, d)
      deleteRow(a, b);
    },
  },
  custom: {
    headRow: 2,
  }
});

//导出excel
function exportExcel() {
  let hideColNum = getHideColNum();
  excel.value.exportExcel("报价单.xlsx", 'office', {
    columns: hideColNum,
    startRowNumber: 1
  })
}

//设置禁止编辑的单元格
function allowRange() {
  let arr = [];
  let bs = orderData.value.template?.baseParameter;
  let rr = orderData.value.template?.headerRow;
  // console.log(config.value.data)
  orderData.value.body.forEach((item, index) => {
    let celldata = item.celldata;
    celldata.forEach((cell, cellIndex) => {
      if (cell.r <= rr) {
        arr.push({
          r: cell.r,
          c: cell.c
        })
      } else {
        if (cell.v.v != null && cell.v.v != '') {
          let p = findParameter(cell.c);
          if (p != null) {
            if (p.inputMethod == 1) {
              let arr = p.dynamicData.d;
              let s = p.dynamicData.s;
              let v = p.dynamicData.v;
              for (let i = 0; i < arr.length; i++) {
                if (arr[i][v] == cell.v.v) {
                  excel.value.setCellValue(cell.r, cell.c, {
                    m: arr[i][s],
                    v: cell.v.v
                  })
                  cell.v.m = arr[i][s];
                  break
                }
              }
            }
          }

        }
      }
    });
  });
  bs?.forEach((item, index) => {
    if (item.inputMethod == 3 || item.inputMethod == 1 || item.inputMethod == 0) {
      arr.push({
        r: -1,
        c: item.index
      })
    }
  })
  excel.value.setUnableEdit(arr);
}

//添加数据行
function addItem() {
  let cc = excel.value.getRange();
  let rowStepNum = Number(rowStep.value);
  rowStartIndex = cc[0].row[0] + 1;
  let color = '#f5f5f5';
  let headRow = orderData.value.template?.headerRow || 2;
  for (let i = 0; i < 999; i++) {
    let v = excel.value.getCellData(headRow, i);
    if (v == null) {
      break;
    }
    let l = mapNumberToLetter(i + 1);
    if (i !== 3 && i !== 4) {
      excel.value.setRangeMerge(0, 'vertical', `${l}${rowStartIndex}:${l}${rowStartIndex + rowStepNum - 1}`);
    }
    excel.value.setRangeBgColor(0, `${l}${rowStartIndex}:${l}${rowStartIndex + rowStepNum - 1}`, color);
    let p = findParameter(i);
    if (p != null) {
      if (p.inputMethod == 0) {
        excel.value.setCellValue(rowStartIndex - 1, i, {
          m: p.fixedValue + "",
          v: p.fixedValue + ""
        });
      } else if (p.inputMethod == 1) {
      } else if (p.inputMethod == 2) {
      } else if (p.inputMethod == 3) {
        let f = generateFormula(rowStartIndex, p.formula);
        if (f != null && f.trim().length > 0) {
          excel.value.setCellValue(rowStartIndex - 1, i, {
            f: f
          });
        }
      }
    }
  }
  rowStartIndex += rowStepNum;
  excel.value.setRangeShow("A" + rowStartIndex + ":A" + rowStartIndex, {});
}

//生成单元格公式
function generateFormula(rowStartIndex: number, formula: string) {
  if (formula && formula.trim().length > 0) {
    let bs = orderData.value.template?.baseParameter;
    if (bs) {
      for (let i = 0; i < bs.length; i++) {
        let b = bs[i];
        formula = formula.replace(b.name, `${b.symbol}${rowStartIndex}`);
        // console.log(formula, b.name);
      }
    }
  }
  return formula;
}

//查找head参数
function findParameter(col: number) {
  let bs = orderData.value.template?.baseParameter;
  let f = null;
  if (bs) {
    for (let i = 0; i < bs.length; i++) {
      let b = bs[i];
      if (b.index == col) {
        f = b;
        break;
      }
    }
  }
  return f;
}

//删除数据行
async function deleteRow(start: number, end: number) {
  const {error} = await fetchDeleteRowByOrder({
    id: orderId.value,
    params: {
      start: start,
      end: end
    }
  });
  if (!error) {
    message.success('保存成功');
  }
}

//保存表格数据
async function save() {
  orderData.value.body = getSheetData();
  const {error} = await fetchUpdateOrder(orderData.value);
  if (!error) {
    message.success('保存成功');
  }
}

//获取隐藏列下标
function getHideColNum() {
  let row = orderData.value.template?.headerRow;
  let col = 100;
  let hideColNum = [];
  for (let i = 0; i < col; i++) {
    let val = excel.value.getCellData(row, i);
    if (val == null) {
      break;
    }
    let purview = currentMember.value?.purview;
    let exist = purview?.find(item => item === val);
    if (!exist) {
      hideColNum.push(i)
    }
  }
  return hideColNum;
}

//获得成员
async function getMemberByOrder() {
  const {error, data} = await fetchGetMemberByOrder({
    params: {
      orderId: orderId.value
    }
  });
  if (!error) {
    currentMember.value = data;
  }
}

//单元格双击事件
const modalData = ref({});
const modalDataType = ref('');
const {bool: modalVisible, setTrue: openModal} = useBoolean();

function cellDoubleClick(cell: any, position: any, sheet: any, ctx: any) {
  let r = position.r;
  let c = position.c;
  let p = findParameter(c);
  let v = cell ? cell.v : '';
  let m = cell ? cell.m : '';
  if (p != null) {
    if (p.inputMethod == 1) {
      modalDataType.value = p.inputMethod;
      modalData.value = {
        r: r,
        c: c,
        d: {
          d: p.dynamicData.d,
          s: p.dynamicData.s,
          h: p.dynamicData.h,
          v: p.dynamicData.v
        },
        v: v,
        m: m
      };
      // console.log("cellDoubleClick:", v,m)
      openModal();
    }
  }
  // console.log("cellDoubleClick:",cell, position, sheet, ctx);
}


function modalConfirm(d) {
  // console.log("modalConfirm:", d);
  excel.value.setCellValue(d.r, d.c, {
    m: d.m,
    v: d.v
  });
}

function getSheetData() {
  return excel.value.getSheetData();
}

//后台获取表格数据
async function getOrderData(id: number) {
  const {error, data} = await fetchGetOrder({
    params: {
      filters: [
        {
          property: 'id',
          operator: 'eq',
          value: id
        }
      ]
    }
  });
  if (!error) {

    orderData.value = data;
    config.value.data = orderData.value.tableData.body;

    excel.value.reloadConfig()

    setTimeout(() => {
      getMemberByOrder();

      allowRange();
    }, 1000)
  }
}

getOrderData(orderId.value);
onMounted(() => {

});


watch(() => showBaseConfigModal.value, (newVal) => {
  if (!newVal) {

  }
})
</script>

<template>
  <n-space vertical style="padding-bottom: 0">
    <n-layout :style="{height: (innerHeight - 115) + 'px'}">
      <n-layout-header style="padding: 5px 5px 0;">
        <n-space style="gap: 5px 5px ">
          <n-button tertiary size="small" type="primary" @click="save">
            保存
          </n-button>
          <n-button tertiary size="small" type="primary" @click="exportExcel">
            导出
          </n-button>
          <n-input-group>
            <n-input size="small" :style="{ width: '35px' }" v-model:value="rowStep"/>
            <n-button size="small" type="primary" ghost @click="addItem">
              添加
            </n-button>
          </n-input-group>
        </n-space>
      </n-layout-header>
      <n-layout-content :content-style="{height: (innerHeight - 150) + 'px',padding:'5px'}">
        <Excel ref="excel" :config="config" v-show="showExcel" @cellDoubleClick="cellDoubleClick"/>
      </n-layout-content>
      <n-layout-footer style="padding: 0;"></n-layout-footer>
    </n-layout>
    <DataInput @confirm="modalConfirm" v-model:showModal="modalVisible" :da="modalData" :type="modalDataType"/>
  </n-space>

</template>

<style scoped>

</style>
